#include "datareader.h"
#include "dataaevent.h"
#include "databevent.h"
#include "dataareader.h"
#include "databreader.h"

#include <iostream>

namespace Lab1
{
    std::chrono::steady_clock::time_point lastTimeResponseA;
    std::chrono::steady_clock::time_point lastTimeResponseB;

    DataReader::DataReader()
        : deviceAisValid( false )
        , deviceBisValid( false )
    {
    }

    void DataReader::start()
    {
        lastTimeResponseA = std::chrono::steady_clock::now();
        lastTimeResponseB = std::chrono::steady_clock::now();

        auto maxResponseTime = DataAReader::ResponseTime < DataBReader::ResponseTime
                                ? DataBReader::ResponseTime: DataAReader::ResponseTime;
        while( true )
        {
            std::shared_ptr< const Event > event = queue.pop(maxResponseTime);
            if(event)
                handleEvent(event);

            if( !deviceAworkDone && deviceAisValid &&  std::chrono::steady_clock::now() - lastTimeResponseA > DataAReader::ResponseTime  )
            {
                std::cout << "Устройство А недоступно" << std::endl;
                deviceAisValid = false;
            }
            if( !deviceBworkDone && deviceBisValid &&  std::chrono::steady_clock::now() - lastTimeResponseB > DataBReader::ResponseTime )
            {
                std::cout << "Устройство B недоступно" << std::endl;
                deviceBisValid = false;
            }
            if(!deviceAisValid && !deviceBisValid)
            {
                std::cout << "Оба устройства недоступны" <<  std::endl;
                return;
            }
            if(deviceAworkDone && deviceBworkDone)
            {
                std::cout << "Оба устройства завершились штатно" <<  std::endl;
                return;
            }
            if((!deviceAisValid || !deviceBisValid) && (deviceAworkDone || deviceBworkDone))
                return;
        }
    }

    EventQueue & DataReader::getQueue()
    {
        return queue;
    }

    void DataReader::handleEvent( const std::shared_ptr< const Event > & event )
    {
        Event::eType eventType = event->getType();
        Event::eSource source = event->getSource();

        if( source == Event::DEVICE_A )
        {
            lastTimeResponseA = std::chrono::steady_clock::now();
        }
        else
        {
            lastTimeResponseB = std::chrono::steady_clock::now();
        }

        switch (eventType) {
        case Event::eType::STARTED:
            {
                if( source == Event::DEVICE_A )
                {
                    std::cout << "Начато чтение с устройства A" << std::endl;
                    deviceAisValid = true;
                }
                else
                {
                    std::cout << "Начато чтение с устройства B" << std::endl;
                    deviceBisValid = true;
                }
            }
            break;
        case Event::eType::WORK_DONE:
            {
                if( source == Event::DEVICE_A )
                {
                    std::cout << "Завершено чтение с устройства A" << std::endl;
                    deviceAworkDone = true;
                }
                else
                {
                    std::cout << "Завершено чтение с устройства B" << std::endl;
                    deviceBworkDone = true;
                }
            }
            break;
        case Event::eType::DATA_DEVICE_A:
            {
                std::cout << "Данные с устройства A: ";
                std::cout << static_cast < const DataAEvent * > ( event.get() )->getData() << std::endl;
            }
            break;
        case Event::eType::DATA_DEVICE_B:
            {
                std::cout << "Данные с устройства B: ";
                std::vector < int > data = static_cast < const DataBEvent * > ( event.get() )->getData();
                for( unsigned int i = 0; i < data.size(); ++i )
                {
                    std::cout << data[i] << " ";
                }
                std::cout << std::endl;
            }
            break;

        default:
            std::cout << "Неподдерживаемый тип события" << std::endl;
        }
    }
}
